package com.wxxymaker.edu.service;

import com.blade.ioc.annotation.Bean;
import com.blade.ioc.annotation.Inject;
import com.blade.kit.CollectionKit;
import com.wxxymaker.edu.model.entity.Ask;
import com.wxxymaker.edu.model.entity.Course;
import com.wxxymaker.edu.model.entity.Task;
import com.wxxymaker.edu.model.entity.User;
import io.github.biezhi.anima.Anima;
import io.github.biezhi.anima.core.AnimaQuery;
import io.github.biezhi.anima.core.Joins;
import io.github.biezhi.anima.enums.OrderBy;
import io.github.biezhi.anima.page.Page;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static io.github.biezhi.anima.Anima.select;
import static io.github.biezhi.anima.Anima.update;

/**
 * @author zyx
 * @date 2018/9/27 - 21:37
 */
@Bean
@Slf4j
public class AskService implements Service<Ask> {

    @Inject
    private AskResultService resultService;

    @Override
    public Ask add(Ask ask) {
        boolean rollback = Anima.atomic(() -> {
            Integer pk = ask.save().asInt();
            ask.setId(pk);
        }).catchException(e -> {
            log.error("添加失败{}", e.getMessage());
        }).isRollback();
        return rollback ? null : ask;
    }

    public Page<Ask> getAskById(Integer id) {
        AnimaQuery<Ask> askAnimaQuery = Anima.select().from(Ask.class)
                .where(Ask::getId, id)
                .join(Joins.with(Course.class)
                        .as(Ask::getCourse)
                        .on(Ask::getCourseId, Course::getId))
                .join(Joins.with(User.class)
                        .as(Ask::getUser)
                        .on(Ask::getUserId, User::getId))
                .join(Joins.with(Task.class)
                        .as(Ask::getTask)
                        .on(Ask::getTaskId, Task::getId))
                .order(Ask::getTime, OrderBy.DESC);

        return askAnimaQuery.page(1,1);
    }

    public Page<Ask> getAllAskById(Integer id, Integer page, Integer size) {
        AnimaQuery<Ask> askAnimaQuery = Anima.select()
                .from(Ask.class)
                .where(Ask::getUserId, id)
                .join(Joins.with(Course.class)
                        .as(Ask::getCourse)
                        .on(Ask::getCourseId, Course::getId))
                .join(Joins.with(User.class)
                        .as(Ask::getUser)
                        .on(Ask::getUserId, User::getId))
                .join(Joins.with(Task.class)
                        .as(Ask::getTask)
                        .on(Ask::getTaskId, Task::getId))
                .order(Ask::getTime, OrderBy.DESC);

        return askAnimaQuery.page(page, size);
    }

    public Page<Ask> getAskByKidWid(Integer kid, Integer tid, Integer page, Integer size) {
        AnimaQuery<Ask> askAnimaQuery = Anima.select().from(Ask.class)
                .where(Ask::getCourseId, kid)
                .where(Ask::getTaskId, tid)
                .join(Joins.with(User.class)
                        .as(Ask::getUser)
                        .on(Ask::getUserId, User::getId))
                .join(Joins.with(Task.class)
                        .as(Ask::getTask)
                        .on(Ask::getTaskId, Task::getId))
                .join(Joins.with(Course.class)
                        .as(Ask::getCourse)
                        .on(Ask::getCourseId, Course::getId))
                .order(Ask::getTime, OrderBy.DESC);

        return askAnimaQuery.page(page, size);
    }

    public Page<Ask> getAskByteaId(Integer tid, Integer page, Integer size) {
        AnimaQuery<Ask> askAnimaQuery = Anima.select().from(Ask.class).where(Ask::getTeaId, tid)
                .join(Joins.with(User.class)
                        .as(Ask::getUser)
                        .on(Ask::getUserId, User::getId))
                .join(Joins.with(Task.class)
                        .as(Ask::getTask)
                        .on(Ask::getTaskId, Task::getId))
                .join(Joins.with(Course.class)
                        .as(Ask::getCourse)
                        .on(Ask::getCourseId, Course::getId))
                .order(Ask::getTime, OrderBy.DESC);

        return askAnimaQuery.page(page, size);
    }

    @Override
    public Ask delete(Object pk) {
        Ask ask = byId(pk);
        boolean rollback = Anima.atomic(ask::delete)
                .catchException(e -> {
                    log.error("删除失败!{}", e.getMessage());
                }).isRollback();
        return rollback ? null : ask;
    }

    @Override
    public boolean change(Ask ask) {
        return false;
    }

    public Page<Ask> getByKid(Integer kid, Integer page, Integer size) {
        AnimaQuery<Ask> from = Anima.select().from(Ask.class)
                .join(Joins.with(Course.class)
                        .as(Ask::getCourse)
                        .on(Ask::getCourseId, Course::getId))
                .join(Joins.with(User.class)
                        .as(Ask::getUser)
                        .on(Ask::getUserId, User::getId))
                .join(Joins.with(Task.class)
                        .as(Ask::getTask)
                        .on(Ask::getUserId, Task::getId))
                .order(Ask::getTime, OrderBy.DESC);
        if (kid > 0) {
            from.where(Ask::getCourseId, kid);
        }
        return from.page(page, size);
    }

    @Override
    public Ask byId(Object pk) {
        return (select().from(Ask.class).byId(pk));
    }

    public Integer updateByWidlooks(Integer wid, Integer looks) {
        return update().from(Ask.class).set("looks", looks + 1).where("id", wid).execute();
    }

    public Integer updateByWidResults(Integer wid, Integer results) {
        return update().from(Ask.class).set("results", results + 1).where("id", wid).execute();
    }

    public Long countByUid(Integer userId) {
        return Anima.select().from(Ask.class)
                .where(Ask::getUserId, userId)
                .count();
    }

    public int deleteByKid(Integer kid) {
        List<Ask> list = Anima.select().from(Ask.class).where(Ask::getCourseId, kid).all();
        if (CollectionKit.isNotEmpty(list)) {
            for (Ask ask : list) {
                ask.delete();
                resultService.deleteByAid(ask.getId());
            }
            return list.size();
        }
        return 0;
    }
}
